from io import BytesIO

from PIL import Image
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
import time
from pprint import pprint
import cv2


def slide_verify():
    is_ok = False
    x = 50
    error_counter = 1
    slide_button = driver.find_element(By.CLASS_NAME, "geetest_slider_button")
    while not is_ok and error_counter < 7:
        x += 7.5
        drag_slide_action = ActionChains(driver)
        drag_slide_action.click_and_hold(slide_button)
        drag_slide_action.pause(0.2)
        drag_slide_action.move_by_offset(x, 0)
        drag_slide_action.pause(0.6)
        drag_slide_action.release()
        drag_slide_action.perform()
        time.sleep(3)
        is_fail_str = str(driver.find_element(By.CLASS_NAME, "geetest_result_title").get_attribute("innerText"))
        print(f'info{is_fail_str}')
        if is_fail_str in ["请正确拼合图像", "请重试"]:
            print(f'第{error_counter}尝试失败了')
            error_counter += 1
        else:
            is_ok = True
    return error_counter == 7


# 51job网址
LOGIN_PAGE_URL = "https://mkt.51job.com/tg/sem/LP_2022_BC.html?from=baidupz&partner=sem_pcbaidupz_2"
driver = webdriver.Edge()
driver.get(LOGIN_PAGE_URL)
driver.maximize_window()
print(f'正在进入以下网站：{driver.title}')
driver.implicitly_wait(5)
# labels = driver.find_elements(By.TAG_NAME, "label")
# print(labels[0].text)
phone_input = driver.find_element(By.NAME, "loginname")
phone_input.send_keys("15316565677")
# print(phone_input.get_property('value'))
# 按钮加载尚未完成
time.sleep(3)
yzm_button = driver.find_element(By.ID, "get_yzm_m")
yzm_button.click()
time.sleep(3)

# 放有验证图片的元素
screenshot = driver.get_screenshot_as_png()
screenshot = Image.open(BytesIO(screenshot))
img = driver.find_element(By.CLASS_NAME, "geetest_window")
location = img.location
size = img.size
# 本机所使用的屏幕缩放比为125%
result = screenshot.crop((location['x'] * 1.25, location['y'] * 1.25,
                          (location['x'] + size['width']) * 1.25, (location['y'] + size['height']) * 1.25))
print(result.size)
result.save("D:\\with_gap.png")
# 通过js将图片上方的缺损和验证图块消去，得到完整图片
js_code = '''document.getElementsByClassName('geetest_canvas_fullbg')[0].style.display="block";'''
driver.execute_script(js_code)
time.sleep(5)
# 获取到截图对象并对图像区域进行截图
screenshot = driver.get_screenshot_as_png()
screenshot = Image.open(BytesIO(screenshot))
result = screenshot.crop((location['x'] * 1.25, location['y'] * 1.25,
                          (location['x'] + size['width']) * 1.25, (location['y'] + size['height']) * 1.25))
result.save("D:\\no_gap.png")

js_code = '''document.getElementsByClassName('geetest_canvas_fullbg')[0].style.display="none";'''
driver.execute_script(js_code)
time.sleep(3)


area_list = list()
img_with_gap = cv2.imread("D:\\with_gap.png")
img_no_gap = cv2.imread("D:\\no_gap.png")
# 将返回该矩形的(最小x，最小y，当前矩形的宽度和长度)
bbox = cv2.selectROI("select", img_with_gap)
cv2.destroyAllWindows()
print(f'当前选中的区域为：{bbox}')
# 高、宽、通道数
for x in range(bbox[2], img_with_gap.shape[1]):
    for y in range(0, img_with_gap.shape[0]):
        pixel1 = img_with_gap[y, x]
        pixel2 = img_no_gap[y, x]
        for i in range(0, 3):
            if abs(int(pixel1[i]) - int(pixel2[i])) >= 60:
                area_list.append((x, y))
                break
for point in area_list:
    cv2.circle(img_with_gap, point, 1, (255, 0, 0), 1)

slide_button = driver.find_element(By.CLASS_NAME, "geetest_slider_button")
time.sleep(1)

# 使用ActionChain模拟验证滑块拖动
drag_action = ActionChains(driver)
print(f"找到的范围为：{area_list}")
print(f"最左边的像素点为：{area_list[0][0]}")
# 总距离修正扩大的25%距离
total_distance = int(area_list[0][0]) * 0.75
drag_actions = ActionChains(driver)
# # 点击，准备拖拽
# drag_actions.click_and_hold(slide_button)
# drag_actions.pause(0.2)
# drag_actions.move_by_offset(total_distance-10, 0)
# drag_actions.pause(0.6)
# drag_actions.move_by_offset(10, 0)
# drag_actions.pause(0.6)
# drag_actions.release()
# drag_actions.perform()   # 释放滑块
time.sleep(3)

result_content = str(driver.find_element(By.CLASS_NAME, "geetest_result_box").get_attribute("innerText"))
if "正确拼合" in result_content or "请重试" in result_content:
    print("滑块验证失败")
    # 滑块验证失败，需要对距离进行修正
    time.sleep(5)
else:
    # 输入验证码
    yzm_input = driver.find_element(By.NAME, "phonecode")
    yzm_str = input("请输入验证码\n")
    yzm_input.send_keys(yzm_str)
    # 点击登陆/注册按钮
    login_btn = driver.find_element(By.ID, "subBtn_m")
    login_btn.click()

print(driver.title)


# while slide_verify():
#     time.sleep(3)
#     reset_button = driver.find_element(By.XPATH, "/html/body/div[2]/div[2]/div[4]/div[3]")
#     print("得到的信息是：" + reset_button.get_attribute("innerText"))
#     reset_button.click()
#     time.sleep(10)
# while slide_verify():

    # click_action = ActionChains(driver)
    # click_action.move_to_element(reset_button).click()
    # time.sleep(3)
# print(labels[1].text)
# yzm_input = driver.find_element(By.NAME, "phonecode")
time.sleep(10)
driver.quit()


# geetest_result_title
